home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
listings
/
v_12_06
/
allison
/
merge2.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-04-08
|
2KB
|
97 lines
LISTING 7 - C implementation of Listing 6
/* merge2.c: Merge up to 15 files to standard output */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXFILES 15
static FILE *mustopen(char *, char *);
struct finfo
{
FILE *f;
char line[BUFSIZ];
};
main(int argc, char *argv[])
{
int i, min_idx;
int nfiles = argc - 1; /* Number of active files */
struct finfo *files;
if (nfiles == 0 || nfiles > MAXFILES)
return EXIT_FAILURE;
/* Open files - read first line */
files = calloc(nfiles,sizeof(struct finfo));
if (!files)
return EXIT_FAILURE;
for (i = 0; i < nfiles; ++i)
{
files[i].f = mustopen(argv[i+1],"r");
fgets(files[i].line,BUFSIZ,files[i].f);
}
/* Do the merge */
while (nfiles)
{
/* INVARIANT: At least one buffer has a fresh line */
/* Determine which lines comes next and print it */
for (min_idx = 0, i = 1; i < nfiles; ++i)
if (strcmp(files[i].line,files[min_idx].line) < 0)
min_idx = i;
fputs(files[min_idx].line,stdout);
/* Get a fresh line from the corresponding file */
if (!fgets(files[min_idx].line,BUFSIZ,files[min_idx].f))
{
/* This file is finished */
fclose(files[min_idx].f);
files[min_idx] = files[--nfiles];
}
}
/* INVARIANT: all files have been closed */
free(files);
return EXIT_SUCCESS;
}
static FILE *mustopen(char *fname, char *mode)
{
FILE *f = fopen(fname,mode);
/* Open file or die */
if (!f)
{
fprintf(stderr,"Can't open %s.\n",fname);
exit(EXIT_FAILURE);
}
return(f);
}
/* Sample execution:
c:>merge2 file1.dat file2.dat file3.dat
and
brown
cow
dog
fox
jumped
jumped
lazy
moon
over
over
quick
the
the
the
the
*/